"""全局数据管理类 - 统一管理配置和缓存数据"""

import json
import yaml
import os
import logging
from typing import Dict, Any, List, Optional
from datetime import datetime, timedelta

from embytools.emby_client import EmbyClient

logger = logging.getLogger(__name__)


class DataManager:
    """全局数据管理器 - 单例模式"""
    
    _instance: Optional['DataManager'] = None
    _lock = False  # 简单的锁机制
    
    # 默认配置文件路径
    CONFIG_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'config', 'config.yaml')
    
    # 默认Emby配置
    DEFAULT_EMBY_CONFIG = {
        'host': '192.168.50.46',
        'port': 8096,
        'https': False,
        'token': '0ffa981958ed498aa646b5689641db6e',
        'name': 'main',
        'user_id': ''
    }
    
    # 缓存过期时间（秒）
    CACHE_TTL = 43200  # 12小时
    
    def __new__(cls):
        """确保只有一个实例"""
        if cls._instance is None:
            cls._instance = super(DataManager, cls).__new__(cls)
            # 初始化
            cls._instance._init_data()
        return cls._instance
    
    def _init_data(self):
        """初始化数据"""
        # 配置数据
        self._config: Dict[str, Any] = {}
        self._config_loaded = False
        
        # Emby客户端
        self._emby_client: Optional[EmbyClient] = None
        
        # 缓存数据
        self._cache: Dict[str, Dict[str, Any]] = {
            'libraries': {'data': [], 'timestamp': None},
            'enabled_libraries': {'data': [], 'timestamp': None},
            'douyin_sources': {'data': [], 'timestamp': None}
        }
    
    # === 配置管理 ===
    
    def load_config(self) -> Dict[str, Any]:
        """加载配置文件"""
        if not self._config_loaded or not self._config:
            try:
                if os.path.exists(self.CONFIG_PATH):
                    with open(self.CONFIG_PATH, 'r', encoding='utf-8') as f:
                        self._config = yaml.safe_load(f) or {}
                    logger.info(f"配置文件加载成功: {self.CONFIG_PATH}")
                else:
                    # 使用默认配置
                    self._config = self._get_default_config()
                    logger.info(f"配置文件不存在，使用默认配置")
                self._config_loaded = True
            except Exception as e:
                logger.error(f"加载配置文件失败: {e}")
                self._config = self._get_default_config()
        return self._config
    
    def save_config(self, config: Optional[Dict[str, Any]] = None) -> bool:
        """保存配置文件"""
        try:
            if config:
                self._config = config
            
            # 确保目录存在
            os.makedirs(os.path.dirname(self.CONFIG_PATH), exist_ok=True)
            
            with open(self.CONFIG_PATH, 'w', encoding='utf-8') as f:
                yaml.dump(self._config, f, allow_unicode=True, default_flow_style=False, sort_keys=False)
            
            logger.info(f"配置文件保存成功: {self.CONFIG_PATH}")
            return True
        except Exception as e:
            logger.error(f"保存配置文件失败: {e}")
            return False
    
    def _get_default_config(self) -> Dict[str, Any]:
        """获取默认配置"""
        return {
            'server': self.DEFAULT_EMBY_CONFIG,
            'phone_playlists': {
                'enabled_libraries': []
            },
            'douyin_sources': {
                'enabled': True,
                'sources': [],
                'sync': {
                    'enabled': False,
                    'interval_hours': 24
                },
                'sync_now': True
            }
        }
    
    # === Emby客户端管理 ===
    
    async def get_emby_client(self) -> Optional[EmbyClient]:
        """获取或初始化Emby客户端"""
        if not self._emby_client:
            await self._init_emby_client()
        return self._emby_client
    
    async def _init_emby_client(self):
        """初始化Emby客户端"""
        try:
            config = self.load_config()
            emby_config = config.get('server', self.DEFAULT_EMBY_CONFIG)
            
            self._emby_client = EmbyClient(emby_config)
            if not await self._emby_client.test_connection():
                logger.error("Emby服务器连接失败")
                self._emby_client = None
                return
            
            await self._emby_client.get_user_id()
            logger.info("Emby客户端初始化成功")
        except Exception as e:
            logger.error(f"初始化Emby客户端失败: {e}")
            self._emby_client = None
    
    # === 媒体库数据管理 ===
    
    async def get_libraries(self, force_refresh: bool = False) -> List[Dict[str, Any]]:
        """获取媒体库列表（带缓存）
        
        Args:
            force_refresh: 是否强制刷新缓存，默认为False
        
        Returns:
            媒体库列表数据
        """
        # 调试打印
        logger.info(f"调用get_libraries方法，force_refresh={force_refresh}")
        cache_valid = self._is_cache_valid('libraries')
        logger.info(f"缓存状态: {'有效' if cache_valid else '无效'}")
        
        # 如果强制刷新或缓存无效，则重新获取数据
        if force_refresh or not cache_valid:
            logger.info("缓存无效或强制刷新，从Emby服务器获取数据")
            try:
                client = await self.get_emby_client()
                if not client:
                    logger.warning("Emby客户端不可用")
                    return []
                
                logger.info("开始从Emby服务器获取媒体库数据...")
                libraries = await client.get_libraries()
                
                # 为每个媒体库获取封面图片URL
                config = self.load_config()
                emby_config = config.get('server', self.DEFAULT_EMBY_CONFIG)
                
                for lib in libraries:
                    try:
                        if lib.get('id'):
                            protocol = 'https' if emby_config.get('https', False) else 'http'
                            lib['cover_url'] = f"{protocol}://{emby_config['host']}:{emby_config['port']}/Items/{lib['id']}/Images/Primary?X-Emby-Token={emby_config['token']}"
                        else:
                            lib['cover_url'] = None
                    except Exception as e:
                        logger.error(f"获取媒体库 {lib.get('name', '未知')} 封面失败: {e}")
                        lib['cover_url'] = None
                
                # 更新缓存
                logger.info(f"获取到 {len(libraries)} 个媒体库，更新缓存")
                self._update_cache('libraries', libraries)
                return libraries
            except Exception as e:
                logger.error(f"获取媒体库列表失败: {e}")
                return []
        
        # 缓存有效，直接返回缓存数据
        logger.info("使用缓存的媒体库数据，直接从内存返回")
        return self._cache['libraries']['data']
    
    # === 手机播放列表数据管理 ===
    
    def get_enabled_libraries(self, force_refresh: bool = False) -> List[str]:
        """获取已启用的媒体库ID列表（带缓存）"""
        # 检查缓存是否有效
        if not force_refresh and self._is_cache_valid('enabled_libraries'):
            logger.debug("使用缓存的已启用媒体库数据")
            return self._cache['enabled_libraries']['data']
        
        # 缓存无效，重新获取
        config = self.load_config()
        enabled_libraries = config.get('phone_playlists', {}).get('enabled_libraries', [])
        
        # 更新缓存
        self._update_cache('enabled_libraries', enabled_libraries)
        return enabled_libraries
    
    def set_library_enabled(self, library_id: str, enabled: bool) -> bool:
        """设置媒体库启用状态"""
        try:
            config = self.load_config()
            
            if 'phone_playlists' not in config:
                config['phone_playlists'] = {'enabled_libraries': []}
            
            enabled_libraries = config['phone_playlists'].get('enabled_libraries', [])
            
            if enabled:
                if library_id not in enabled_libraries:
                    enabled_libraries.append(library_id)
            else:
                if library_id in enabled_libraries:
                    enabled_libraries.remove(library_id)
            
            config['phone_playlists']['enabled_libraries'] = enabled_libraries
            
            # 保存配置
            result = self.save_config(config)
            
            # 清除缓存，下次获取时重新加载
            self._invalidate_cache('enabled_libraries')
            
            return result
        except Exception as e:
            logger.error(f"设置媒体库启用状态失败: {e}")
            return False
    
    # === 抖音数据源管理 ===
    
    def get_douyin_sources(self, force_refresh: bool = False) -> Dict[str, Any]:
        """获取抖音数据源配置（带缓存）"""
        # 检查缓存是否有效
        if not force_refresh and self._is_cache_valid('douyin_sources'):
            logger.debug("使用缓存的抖音数据源配置")
            return self._cache['douyin_sources']['data']
        
        # 缓存无效，重新获取
        config = self.load_config()
        douyin_sources = config.get('douyin_sources', {
            'enabled': True,
            'sources': [],
            'sync': {
                'enabled': False,
                'interval_hours': 24
            },
            'sync_now': False
        })
        
        # 更新缓存
        self._update_cache('douyin_sources', douyin_sources)
        return douyin_sources
    
    def save_douyin_sources(self, douyin_sources: Dict[str, Any]) -> bool:
        """保存抖音数据源配置"""
        try:
            config = self.load_config()
            config['douyin_sources'] = douyin_sources
            
            # 保存配置
            result = self.save_config(config)
            
            # 清除缓存，下次获取时重新加载
            self._invalidate_cache('douyin_sources')
            
            return result
        except Exception as e:
            logger.error(f"保存抖音数据源配置失败: {e}")
            return False
    
    def get_sync_config(self) -> Dict[str, Any]:
        """获取同步配置"""
        config = self.load_config()
        return config.get('sync', {
            'enabled': False,
            'interval_hours': 24
        })
    
    def save_sync_config(self, sync_config: Dict[str, Any]) -> bool:
        """保存同步配置"""
        try:
            config = self.load_config()
            config['sync'] = sync_config
            
            # 保存配置
            result = self.save_config(config)
            
            return result
        except Exception as e:
            logger.error(f"保存同步配置失败: {e}")
            return False
    
    # === 缓存管理 ===
    
    def _is_cache_valid(self, cache_key: str) -> bool:
        """检查缓存是否有效"""
        if cache_key not in self._cache:
            return False
        
        cache = self._cache[cache_key]
        if cache['timestamp'] is None:
            return False
        
        # 检查是否过期
        elapsed = (datetime.now() - cache['timestamp']).total_seconds()
        return elapsed < self.CACHE_TTL
    
    def _update_cache(self, cache_key: str, data: Any):
        """更新缓存"""
        if cache_key not in self._cache:
            self._cache[cache_key] = {'data': None, 'timestamp': None}
        
        self._cache[cache_key] = {
            'data': data,
            'timestamp': datetime.now()
        }
    
    def _invalidate_cache(self, cache_key: Optional[str] = None):
        """使缓存失效"""
        if cache_key:
            # 使特定缓存失效
            if cache_key in self._cache:
                self._cache[cache_key]['timestamp'] = None
                logger.debug(f"缓存已失效: {cache_key}")
        else:
            # 使所有缓存失效
            for key in self._cache:
                self._cache[key]['timestamp'] = None
            logger.debug("所有缓存已失效")
    
    def refresh_all_data(self):
        """刷新所有数据（使所有缓存失效）"""
        self._invalidate_cache()
        self._config_loaded = False  # 强制重新加载配置


# 创建全局数据管理器实例
data_manager = DataManager()


def get_data_manager() -> DataManager:
    """获取数据管理器实例"""
    return data_manager